package graphics.fingerprint;

import command.SimpleActionCommand;

import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.GestureDetector.OnGestureListener;

public class UserController {

	private PaintView view;
	private MarkListener markListener;
	private MoveListener moveListener;

	private int mode;
	public static final int MODE_MARK = 0;
	public static final int MODE_MOVE = 1;
	public static final int MODE_ZOOM = 2;
	public static final int MODECOUNT = 2;

	private int pointer;

	private GestureDetector gd;
	private CommandPusher pusher;

	public static final int POINTER_ARROW = 0;
	public static final int POINTER_PEN = 1;
	public static final int POINTER_ERASER = 2;
	public static final int POINTERCOUNT = 3;

	public UserController(PaintView paintView) {
		this.view = paintView;
		gd = new GestureDetector(this.view.getContext(),
				new MyGestureListener());
		gd.setIsLongpressEnabled(true);

		this.markListener = new MarkListener(this, gd);
		this.moveListener = new MoveListener(this, gd);
		this.view.setOnTouchListener(markListener);
	}

	public UserController(PaintView pv, CommandPusher pusher) {
		this(pv);
		this.setPusher(pusher);
		this.markListener.setPusher(pusher);
	}

	public void changePointer() {
		pointer = (++pointer) % POINTERCOUNT;
		switch (pointer) {
		case UserController.POINTER_ARROW:
			Log.d("Debug&Info", "arrow pointer");
			pusher.pushCommand(SimpleActionCommand.ARROW);
			break;
		case UserController.POINTER_PEN:
			Log.d("Debug&Info", "pen pointer");
			pusher.pushCommand(SimpleActionCommand.PEN);
			break;
		case UserController.POINTER_ERASER:
			Log.d("Debug&Info", "eraser pointer");
			pusher.pushCommand(SimpleActionCommand.ERASER);
			break;
		}
	}

	public void changeMode() {
		mode = (++mode) % MODECOUNT;
		switch (mode) {
		case UserController.MODE_MARK:
			this.view.setOnTouchListener(this.markListener);
			Log.d("Debug&Info", "Mark mode");
			break;
		case UserController.MODE_MOVE:
			this.view.setOnTouchListener(this.moveListener);
			Log.d("Debug&Info", "Move mode");
			break;
		}
	}

	private class MyGestureListener implements OnGestureListener {

		@Override
		public boolean onDown(MotionEvent e) {
			// Log.d("Debug&Info", "onDown");
			return true;
		}

		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float vx,
				float vy) {
			final int MIN_DISTANCE = 20;
			// final int MAX_DISTANCE = 300;
			final int MIN_VELOCITY = 700;
			if (e1.getX() - e2.getX() > MIN_DISTANCE
					&& Math.abs(vx) > MIN_VELOCITY) {
				pusher.pushCommand(SimpleActionCommand.BACK);
				Log.d("Debug&Info", "Fling left+" + vx);
			} else if (e2.getX() - e1.getX() > MIN_DISTANCE
					&& Math.abs(vx) > MIN_VELOCITY) {
				pusher.pushCommand(SimpleActionCommand.NEXT);
				Log.d("Debug&Info", "Fling right+" + vx);
			} else if (e2.getY() - e1.getY() > MIN_DISTANCE
					&& Math.abs(vy) > MIN_VELOCITY) {
				pusher.pushCommand(SimpleActionCommand.NEXT);
				Log.d("Debug&Info", "Fling down+" + vy);
			} else if (e1.getY() - e2.getY() > MIN_DISTANCE
					&& Math.abs(vy) > MIN_VELOCITY) {
				pusher.pushCommand(SimpleActionCommand.BACK);
				Log.d("Debug&Info", "Fling up+" + vy);
			}
			return true;
		}

		@Override
		public void onLongPress(MotionEvent e) {
			// Log.d("Debug&Info", "onLongPress");
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2,
				float distanceX, float distanceY) {
			// Log.d("Debug&Info", "onScroll");
			return true;
		}

		@Override
		public void onShowPress(MotionEvent e) {
			// Log.d("Debug&Info", "onShowPress");
		}

		@Override
		public boolean onSingleTapUp(MotionEvent e) {
			// Log.d("Debug&Info", "onSingleTapUp:" + mode);
			// mode = (++mode) % MODECOUNT;
			// CharSequence txt = "";
			// switch (mode) {
			// case MODE_MARK:
			// txt = "MARK";
			// break;
			// case MODE_MOVE:
			// txt = "MOVE";
			// break;
			// case MODE_ZOOM:
			// txt = "ZOOM";
			// break;
			// }
			// Log.d("Debug&Info", "onSingleTapUp:" + txt);
			return true;
		}
	}

	public int getMode() {
		return mode;
	}

	public int getPointer() {
		return pointer;
	}

	public float getImage_x() {
		return this.moveListener.getImage_x();
	}

	public float getImage_y() {
		return this.moveListener.getImage_y();
	}

	public void setMoveListener(MoveListener moveListener) {
		this.moveListener = moveListener;
	}

	public MoveListener getMoveListener() {
		return moveListener;
	}

	public void setMarkListener(MarkListener markListener) {
		this.markListener = markListener;
	}

	public MarkListener getMarkListener() {
		return markListener;
	}

	public void setPusher(CommandPusher pusher) {
		this.pusher = pusher;
	}

	public CommandPusher getPusher() {
		return pusher;
	}
}
